/* This file is part of Open Source Project, KrishiSuvidha
 * (C) 2010 , Akhil Nulu, Akshaya Datta
 * This is released according to GPL V3
 * InformationDisplay is a class which displays an image and related text on multiple Screens.
 */
 
import java.io.IOException;
import java.lang.String;
import java.util.Vector;
import javax.microedition.lcdui.*;

public class InformationDisplay extends Canvas{
	
	private String Info;
	private static Image image1; // Lines Vector contains the lines into which
	// the information is split.
	
	public Vector Lines = new Vector();// This Variable contains the number of
	// screens that will be used to
	// represent the information.
	
	protected int No_of_Screens = 0;// This maintains the Number of Screen
	// Objects required.
	
	private Screen s;
	public Canvas p ; //p is menu object to which control is handed over on exit.
	private Display display;
	protected Vector List_Of_Screens = new Vector(); // This variable maintains

	// all the Screen
	// Objects

	// in a vector form.
	public InformationDisplay()
	{
		
	}
	
	protected void paint(Graphics G)
	{
		
	}
	
	
	
	public InformationDisplay(String Information, Image img, Display dis,Canvas c) {
	
		image1 = img;
		this.display = dis;
		this.Info = Information;
		this.p = c;
		this.LinesSplitter(Info);
		No_of_Screens = 1;
		
		/*
		 * In the following for loop number of screen objects required will be
		 * calculated
		 */
		
		for (int i = 0; Lines.size() > 9 + (19 * i); i++) {
			No_of_Screens++;
		}
		
		// Based on the Number of Screens found above that many number of Screen
		// objects are created
		// and maintained in the List_Of_Screen array.The Objects attached in
		// the vector is dummy
		// its initialization is followed in the following code.
		
		int counter;
		for (counter = 0; counter < No_of_Screens; counter++) {
			s = new Screen(counter + 1);
			this.List_Of_Screens.addElement((Screen) s);

		}
		
		/*
		 * The following block of code fills the needed indexes of the lines
		 * vector for each screen for it to fill by itself. These indexes are
		 * later used for CommandListener.
		 */

		if (No_of_Screens > 1) {
			for (counter = 0; counter < No_of_Screens; counter++) {
				s = (Screen) this.List_Of_Screens.elementAt(counter);

				if (counter == 0)
					s.LinkScreens(null, (Screen) this.List_Of_Screens
							.elementAt(counter + 1));

				else if (counter > 0 && counter < No_of_Screens - 1)
					s.LinkScreens((Screen) this.List_Of_Screens
							.elementAt(counter - 1),
							(Screen) this.List_Of_Screens
									.elementAt(counter + 1));

				else if (counter == No_of_Screens - 1)
					s.LinkScreens((Screen) this.List_Of_Screens
							.elementAt(counter - 1), null);

			}
			if (No_of_Screens == 1) {
				s = (Screen) this.List_Of_Screens.elementAt(0);
				s.LinkScreens(null, null);
			}
		}

		s = (Screen) this.List_Of_Screens.elementAt(0);
		display.setCurrent(s);

		/*
		 * The Rest of the code defined in this constructor populates each
		 * screen objects with the information to be displayed on that screen.
		 */

		if (No_of_Screens == 1) {
			s = (Screen) this.List_Of_Screens.elementAt(0);
			s.FillInformation(0, Lines.size() - 1);

		}
		if (No_of_Screens > 1) {
			int i = 1;
			s = (Screen) this.List_Of_Screens.elementAt(0);
			s.FillInformation(0, 8);
			while (i + 1 < No_of_Screens) {
				s = (Screen) this.List_Of_Screens.elementAt(i);
				s.FillInformation(9 + 19 * (i - 1), 9 + 19 * i);
				i++;
			}
			if (i + 1 == No_of_Screens) {
				s = (Screen) this.List_Of_Screens.elementAt(i);
				s.FillInformation(9 + 19 * (i - 1), Lines.size() - 1);
			}
		}

	}

	/*
	 * LineSplitter method Divides the String of information in to the /* lines
	 * that can be displayed on the screen.
	 */

	protected void LinesSplitter(String Info) {
		int Start_Index;
		int Last_Index;
		int length = Info.length();
		for (Start_Index = 0, Last_Index = 45; Start_Index < length; Start_Index += 45, Last_Index += 45) {
			if (Last_Index < length)
				Lines.addElement(Info.substring(Start_Index, Last_Index));
			else
				Lines.addElement(Info.substring(Start_Index, length - 1));

		}
	}

	class Screen extends Canvas implements CommandListener {
		private Screen S1, S2;// These variables are previous Screen and next
		// Screen Objects.
		private int Screen_Number;
		private Command exit, next, back;
		private int First_Index, Last_Index; // These variables are the indices

		// of the Lines Vector that
		// contains the information to
		// be displayed by this Screen
		// Object.

		public Screen(int no) {

			First_Index = 0;
			Last_Index = 0;
			// this.S1 = null;
			// this.S2 = null;
			Screen_Number = no;
			// The following Section Creates Buttons to be displayed on each
			// Screen.
			if (No_of_Screens > 1) {
				if (this.Screen_Number == 1) {
					exit = new Command("Exit", Command.EXIT, 1);
					next = new Command("Next", Command.SCREEN, 2);
					addCommand(exit);
					addCommand(next);
				}

				if (this.Screen_Number > 1
						&& this.Screen_Number != No_of_Screens) {
					next = new Command("Next", Command.SCREEN, 2);
					back = new Command("Back", Command.EXIT, 1);
					addCommand(back);
					addCommand(next);
				}

				try {
					if (this.Screen_Number == No_of_Screens)
						back = new Command("Back", Command.SCREEN, 2);
					exit = new Command("Exit", Command.EXIT, 1);
					addCommand(back);
					addCommand(exit);
				} catch (NullPointerException e) {
				}
			}
			if (No_of_Screens == 1) {
				exit = new Command("Exit", Command.EXIT, 1);
				addCommand(exit);
			}

			setCommandListener(this);
		}
		//This Links the previous and next Screen objects to this Screen Object
		public void LinkScreens(Screen S1, Screen S2) {
			this.S1 = S1;
			this.S2 = S2;
		}
		
		protected void FillInformation(int First_Index, int Last_Index) {
			this.First_Index = First_Index;
			this.Last_Index = Last_Index;
			try {
				repaint();
			} catch (NullPointerException e) {

			}
		}

		/* This Paints the Canvas with the String of Information and Image*/
		protected void paint(Graphics g) {

			Font font = null;
			g.setColor(255, 255, 255);
			g.fillRect(0, 0, getWidth(), getHeight());
			g.setColor(0, 0, 255);
			font = Font.getDefaultFont();
			int k = 0;

			if (Screen_Number > 1) {

				for (int i = this.First_Index; i <= this.Last_Index; i++) {
					g
							.drawString((String) Lines.elementAt(i), 5, k
									* font.getHeight(), Graphics.BOTTOM
									| Graphics.LEFT);
					k++;
				}
			}
			if (Screen_Number == 1) {
				if (Last_Index != 0) {
					g.drawImage(image1, getWidth() / 2, getHeight() / 4,
							Graphics.HCENTER | Graphics.VCENTER);
				}
				for (int i = First_Index; i <= Last_Index; i++) {
					g.drawString((String) Lines.elementAt(i), 5, getHeight()
							/ 2 + k * font.getHeight(), Graphics.BOTTOM
							| Graphics.LEFT);
					k++;
				}
			}

		}
		
		//The following function defines what each command will do.
		public void commandAction(Command c, Displayable d) {

			String label = c.getLabel();
			if (label.equals("Next") && S2 != null)
				display.setCurrent(S2);

			if (label.equals("Back") && S1 != null)
				display.setCurrent(S1);

			if (label.equals("Exit"))
				display.setCurrent(p);

		}

	}
}
